#include "Nodo.h"

Nodo::Nodo(string nombre, int numID, int nivel, bool esDirectorio) {
	this->nombre = nombre;
	this->esDirectorio = esDirectorio;
	this->numHijos = 0;
	if (this->nombre == "root") {
		this->padre = NULL;
		this->numId = 0;
		this->nivel = 0;
	} else {
		this->padre = padre;
		this->numId = numID;
		this->nivel = nivel;
	}
	if (this->esDirectorio) {
		this->tamano = 4096;
	}
}

Nodo::~Nodo() {
	if (this->hijos.size() > 0) {
		unsigned int i;
		for (i=0; i<this->hijos.size(); i++) {
			this->hijos.clear();
		}
	}
	if (this->idBloqueIndice.size() > 0) {
		unsigned int i;
		for (i=0; i<this->idBloqueIndice.size(); i++) {
			this->idBloqueIndice.clear();
		}
	}
}

void Nodo::MostrarPadreHijos() {
	cout << "Los nombres del padre, de los hijos, del espiritu santo, amén son:\n";
	unsigned int i;
	cout << "Hijos:\n\n";
	for (i=0; i<this->hijos.size(); i++) {
		cout << this->hijos[i]->nombre << "\n";
	}
	cout << "\nPadre: " << this->nombre << "\n";
}

bool Nodo::EsHijo(unsigned int nodoId) {
	unsigned int i=0;
	bool es = false;
	while (i<this->hijos.size() && !es) {
		es = this->hijos[i]->numId == nodoId;
		if (!es) {
			i++;
		}
	}
	return es;
}

unsigned int Nodo::IndexOf(unsigned int nodoId) {
	unsigned int i=0;
	bool encontrado = false;
	while (i<this->hijos.size() && !encontrado) {
		encontrado = this->hijos[i]->numId == nodoId;
		if (!encontrado) {
			i++;
		}
	}
	return i;
}

Nodo* Nodo::AnadirHijo(Nodo* nodo) {
	if (!this->EsHijo(nodo->numId)) {
		this->hijos.insert(this->hijos.end(),nodo);
		nodo->padre = this;
		this->numHijos++;
		return nodo;
	} else {
		return NULL;
	}
}

Nodo* Nodo::BuscarHijo(unsigned int nodoId) {
	if(this->EsHijo(nodoId)) {
		return this->hijos[this->IndexOf(nodoId)];
	} else {
		return NULL;
	}
}

void Nodo::ActualizarNodo(unsigned int nodoId, string nombre, off_t tamano, time_t ultimaModificacion) {
	if(this->EsHijo(nodoId)) {
		this->hijos[this->IndexOf(nodoId)]->nombre = nombre;
		this->hijos[this->IndexOf(nodoId)]->tamano = tamano;
		this->hijos[this->IndexOf(nodoId)]->ultimaModificacion = ultimaModificacion;
	}
}

void Nodo::EliminarNodo(unsigned int nodoId) {
	if(!this->hijos.empty() && this->EsHijo(nodoId) && (this->hijos[this->IndexOf(nodoId)]->hijos.size() == 0)) {
		this->hijos.erase(this->hijos.begin()+this->IndexOf(nodoId));
		this->numHijos--;
	} else {
		if (this->hijos[this->IndexOf(nodoId)]->hijos.size() != 0)
			cout << "No se puede eliminar porque no está vacío.\n";
	}
}

bool Nodo::GetEsDir() {
	return this->esDirectorio;
}

off_t Nodo::GetTamano() {
	return this->tamano;
}

time_t Nodo::GetUltMod() {
	return this->ultimaModificacion;
}

int Nodo::ChildNum() {
	return this->hijos.size();
}

Nodo* Nodo::GetHijo(int index) {
	return this->hijos[index];
}

Nodo* Nodo::GetPadre() {
	return this->padre;
}

string Nodo::GetNombre() {
	return this->nombre;
}

unsigned int Nodo::GetNumId() {
	return this->numId;
}

int Nodo::GetNivel() {
	return this->nivel;
}

int Nodo::GetNumHijos() {
	return this->numHijos;
}
int Nodo::GetBloqueIndiceByIndex(int i){
	return this->idBloqueIndice[i];
}

int Nodo::GetNumBloques() {
	return this->idBloqueIndice.size();
}

void Nodo::AnadirBloqueIndice(int bloqI){
	this->idBloqueIndice.insert(this->idBloqueIndice.end(),bloqI);
}

void Nodo::EliminarBloqueIndice() {
	this->idBloqueIndice.clear();
}

void Nodo::SetNumHijos(int nHijos) {
	this->numHijos = nHijos;
}

void Nodo::SetNombre(string nomNuevo) {
	this->nombre = nomNuevo;
}

void Nodo::SetNumId(unsigned int numId) {
	this->numId = numId;
}

void Nodo::SetTamano(off_t tam) {
	this->tamano = tam;
}

void Nodo::SetTimeUltId(time_t tim) {
	this->ultimaModificacion = tim;
}

void Nodo::SetEsDir(bool dir) {
	this->esDirectorio = dir;
}

Nodo* Nodo::GetNodoByNom(string nombre) {
	unsigned int i=0;
	bool encontrado=false;
	while (i<this->hijos.size() && !encontrado) {
		encontrado = this->hijos[i]->GetNombre() == nombre;
		if (!encontrado) {
			i++;
		}
	}
	if (encontrado) {
		return this->hijos[i];
	} else {
		return NULL;
	}
}

Nodo* Nodo::CopiarNodo() {
	Nodo* nuevo = new Nodo(this->GetNombre(),0,this->GetNivel(),this->GetEsDir());
	return nuevo;
}
